From 29fbda7e15c6eb16ac9513d0c1838b087a68e055 Mon Sep 17 00:00:00 2001 From: Julien Grall Date: Tue, 28 Apr 2015 15:32:32 +0100 Subject: [PATCH] xen/passthrough: arm: release the DT devices assigned to a guest earlier The toolstack may not have deassigned every device used by a guest. Therefore we have to go through the device list and remove them before asking the IOMMU drivers to release memory for this domain. This can be done by moving the call to the release function when we relinquish the resources. The IOMMU part will be destroyed later when the domain is freed. Signed-off-by: Julien Grall Signed-off-by: Robert VanVossen Acked-by: Jan Beulich Acked-by: Ian Campbell --- xen/arch/arm/domain.c | 4 ++++ xen/drivers/passthrough/arm/iommu.c | 1 - xen/drivers/passthrough/device_tree.c | 7 ++++++- xen/include/xen/iommu.h | 2 +- 4 files changed, 11 insertions(+), 3 deletions(-) diff --git a/xen/arch/arm/domain.c b/xen/arch/arm/domain.c index 180bccc676..24b89380f8 100644 --- a/xen/arch/arm/domain.c +++ b/xen/arch/arm/domain.c @@ -795,6 +795,10 @@ int domain_relinquish_resources(struct domain *d) switch ( d->arch.relmem ) { case RELMEM_not_started: + ret = iommu_release_dt_devices(d); + if ( ret ) + return ret; + d->arch.relmem = RELMEM_xen; /* Fallthrough */ diff --git a/xen/drivers/passthrough/arm/iommu.c b/xen/drivers/passthrough/arm/iommu.c index 92346579a9..95b1abb972 100644 --- a/xen/drivers/passthrough/arm/iommu.c +++ b/xen/drivers/passthrough/arm/iommu.c @@ -66,7 +66,6 @@ int arch_iommu_domain_init(struct domain *d) void arch_iommu_domain_destroy(struct domain *d) { - iommu_dt_domain_destroy(d); } int arch_iommu_populate_page_table(struct domain *d) diff --git a/xen/drivers/passthrough/device_tree.c b/xen/drivers/passthrough/device_tree.c index 4d82a09759..05ab274305 100644 --- a/xen/drivers/passthrough/device_tree.c +++ b/xen/drivers/passthrough/device_tree.c @@ -105,7 +105,7 @@ int iommu_dt_domain_init(struct domain *d) return 0; } -void iommu_dt_domain_destroy(struct domain *d) +int iommu_release_dt_devices(struct domain *d) { struct hvm_iommu *hd = domain_hvm_iommu(d); struct dt_device_node *dev, *_dev; @@ -115,7 +115,12 @@ void iommu_dt_domain_destroy(struct domain *d) { rc = iommu_deassign_dt_device(d, dev); if ( rc ) + { dprintk(XENLOG_ERR, "Failed to deassign %s in domain %u\n", dt_node_full_name(dev), d->domain_id); + return rc; + } } + + return 0; } diff --git a/xen/include/xen/iommu.h b/xen/include/xen/iommu.h index e9d2d5c280..d9c9ede279 100644 --- a/xen/include/xen/iommu.h +++ b/xen/include/xen/iommu.h @@ -117,7 +117,7 @@ void iommu_read_msi_from_ire(struct msi_desc *msi_desc, struct msi_msg *msg); int iommu_assign_dt_device(struct domain *d, struct dt_device_node *dev); int iommu_deassign_dt_device(struct domain *d, struct dt_device_node *dev); int iommu_dt_domain_init(struct domain *d); -void iommu_dt_domain_destroy(struct domain *d); +int iommu_release_dt_devices(struct domain *d); #endif /* HAS_DEVICE_TREE */ -- 2.30.2